package org.ftc.dao; 

import java.util.Iterator;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.ftc.domain.Users;
import org.ftc.form.UsersForm;
import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

@Repository
public class UsersDao extends CurrentDao <Users, String> {

	@Override
	public Users load(String id) {
		return super.load(id);
	}

	@Override
	public Users get(String id) {
		return super.get(id);
	}

	@Override
	public synchronized boolean save(Users entity) {
		return super.save(entity);
	}

	@Override
	public synchronized boolean saveOrUpdate(Users entity) {
		return super.saveOrUpdate(entity);
	}

	@Override
	public synchronized boolean update(Users entity) {
		boolean x = super.update(entity);
		return x;
	}

	@Override
	public synchronized boolean delete(Users entity) {
		return super.delete(entity);
	}

	@Override
	public synchronized boolean delete(String id) {
		return super.delete(id);
	}

	@Override
	public List<Users> findPage(int offset, int pageSize) {
		return super.findPage(offset, pageSize);
	}

	@Override
	public List<Users> findAll() {
		return super.findAll();
	}

	@Override
	public long countAll() {
		return super.countAll();
	}
	
	@SuppressWarnings("unchecked")
	public List<Users> findPage(UsersForm form, int offset, int pageSize) {
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			criteriaWsql(form, criteria);
			criteriaSort(form, criteria);
			criteria.add(Restrictions.eq("status2", "0" ));
			criteria.addOrder(Order.asc("deptCode"));
			criteria.addOrder(Order.asc("decLevel"));
			criteria.setFirstResult(offset);
			criteria.setMaxResults(pageSize);
			List<Users> list = (List<Users>) criteria.list();
			return list; 
		}catch( Exception e ){
			e.printStackTrace();
			getLog().error(e.toString());
			return null;
		}
	}
	
	public long count(UsersForm form) {
		try{	
			Criteria criteria = getSession().createCriteria(Users.class); 
			criteria.add(Restrictions.eq("status2", "0" ));
		    criteria.setProjection(Projections.rowCount()); 
		    criteriaWsql(form, criteria);
		    return (Long) criteria.uniqueResult();
		}catch( Exception e ){
			getLog().error(e.toString());
			return 0; 
		}
	}
	
	@SuppressWarnings("unchecked")
	public List<Users> findByName(UsersForm form) {
		try {
			Criteria criteria = getSession().createCriteria(Users.class);
			if (StringUtils.isNotBlank(form.getName())) {
				criteria.add(Restrictions.or(
						Restrictions.ilike("name",form.getName(), MatchMode.ANYWHERE)
				));
			}
			return (List<Users>) criteria.list();
		} catch (Exception e) {
			getLog().error(e.toString());
			return null;
		}
	}
	
	private void criteriaWsql(UsersForm form, Criteria criteria){
		if( form.getName() != null && form.getName().length() > 0  )
			criteria.add(Restrictions.ilike("name", form.getName() ,MatchMode.ANYWHERE));
		
		if( form.getType() != null && form.getType().length() > 0  )
			criteria.add(Restrictions.eq("type", form.getType()));
		
		if( form.getRole() != null && form.getRole().length() > 0  )
			criteria.add(Restrictions.eq("role", form.getRole())); 
		
		if( form.getEmail() != null && form.getEmail().length() > 0  )
			criteria.add(Restrictions.eq("email", form.getEmail() ));
		
		if( form.getUserName() != null && form.getUserName().length() > 0  )
			criteria.add(Restrictions.ilike("userName", form.getUserName() ,MatchMode.ANYWHERE));
		
		if( form.getStatus() != null && form.getStatus() >= 0  )
			criteria.add(Restrictions.eq("status", form.getStatus() ));
		
		
//		if( StringUtils.isNotBlank(form.getMainOrg())){
//			DetachedCriteria subQuery = DetachedCriteria.forClass(Organization.class);
//			subQuery.add(Restrictions.eq("parentOrganSeq", form.getMainOrg() )).setProjection(Property.forName("orgSeq"));
//			criteria.add(Restrictions.or(
//					Restrictions.eq("codeOrgan", form.getMainOrg() ),
//					Property.forName("codeOrgan").in(subQuery)
//					));
//		}
			
	}
	
	@SuppressWarnings("unchecked")
	public Users findUserByIdEmail(String userName, String email) {
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			criteria.add( Restrictions.eq("userName", userName ) );
			criteria.add( Restrictions.eq("email", email ) );
			List<Users> list =  criteria.list();
			for(Iterator<Users> it =list.iterator(); it.hasNext(); )
				return (Users)it.next(); 
			return null;  
		}catch( Exception e ){
			return null;
		}
	}
	
	@SuppressWarnings("unchecked")
	public Users loginUserName(String userName){
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			criteria.add( Restrictions.eq("userName", userName ) );
			criteria.setCacheable(true);
			List<Users> list =  criteria.list();
			for(Iterator<Users> it =list.iterator(); it.hasNext(); )
				return (Users)it.next(); 
			return null;  
		}catch( Exception e ){ 
			e.printStackTrace();
			return null;
		}
    }
	
	@SuppressWarnings("unchecked")
	public Users findByUserName(String userName){
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			criteria.add( Restrictions.eq("userName", userName ) );
			criteria.setCacheable(true);
			List<Users> list =  criteria.list();
			for(Iterator<Users> it =list.iterator(); it.hasNext(); )
				return (Users)it.next(); 
			return null;  
		}catch( Exception e ){
			return null;
		}
    }
	
	@SuppressWarnings("unchecked")
	public Users findByUserId(String userName){
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			criteria.add( Restrictions.eq("userName", userName ) );
			criteria.add( Restrictions.eq("status", 0 ) );
			criteria.setCacheable(true);
			List<Users> list =  criteria.list();
			for(Iterator<Users> it =list.iterator(); it.hasNext(); )
				return (Users)it.next(); 
			return null;  
		}catch( Exception e ){
			return null;
		}
    }
	
	@SuppressWarnings("unchecked")
	public List<Users> findType(String type){
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			criteria.add( Restrictions.eq("type", type ) );
			criteria.setCacheable(true);
			return criteria.list();
		}catch( Exception e ){
			return null;
		}
    }
	
	@SuppressWarnings("unchecked")
	public List<Users> findUser(UsersForm userForm){
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			if(StringUtils.isNotBlank(userForm.getUserName())){
				criteria.add( Restrictions.ilike("userName", userForm.getUserName(), MatchMode.ANYWHERE ) );
			}
			if(StringUtils.isNotBlank(userForm.getName())){
				criteria.add( Restrictions.ilike("name", userForm.getName(),MatchMode.ANYWHERE ) );
			}
			criteria.setCacheable(true);
			List<Users> list =  criteria.list();
				return list; 
		}catch( Exception e ){
			return null;
		}
	}
	
	@SuppressWarnings("unchecked")
	public Users findByUserNameOrName(String userName){
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			criteria.add( 
				Restrictions.or(
					Restrictions.eq("userName", userName ),
					Restrictions.eq("name", userName ) 
				)
			);
			criteria.setCacheable(true);
			List<Users> list =  criteria.list();
			for(Iterator<Users> it =list.iterator(); it.hasNext(); )
				return (Users)it.next(); 
			return null;  
		}catch( Exception e ){
			return null;
		}
    }
	
	@SuppressWarnings("unchecked")
	public Users findByEmailType(String email, String type){
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			criteria.add( Restrictions.eq("email", email ) );
			criteria.add( Restrictions.eq("type", type ) ); 
			List<Users> list =  criteria.list();
			for(Iterator<Users> it =list.iterator(); it.hasNext(); )
				return (Users)it.next(); 
			return null;  
		}catch( Exception e ){
			return null;
		}
    }
	
	@SuppressWarnings("unchecked")
	public List<Users> findByRole( String role){
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			String sql = "select role_seq from role_auth where auths like '%" + role + "%'";
			criteria.add( Restrictions.sqlRestriction("{alias}.role in (" + sql + ") ") ); 
			criteria.add( Restrictions.eq("type", "USERS" ) ); 
			return criteria.list();
		}catch( Exception e ){
			return null; 
		}
    }
	
	@SuppressWarnings("unchecked")
	public List<Users> findByCodeOrgan( String codeOrgan ){
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			criteria.add( Restrictions.eq("codeOrgan", codeOrgan) ); 
			criteria.add( Restrictions.eq("type", "USERS" ) ); 
			return criteria.list();
		}catch( Exception e ){
			return null;
		}
    }
	
	public List<Users> findByTeamUsersSeq(String... teamUsersSeq) {
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			criteria.add(Restrictions.in("usersSeq", teamUsersSeq ));
			criteria.add( Restrictions.eq("type", "HOST" ) ); 
			criteria.setCacheable(true);
			return getList(criteria);
		}catch( Exception e ){
			getLog().error(e.toString());
			return null;
		}
	}
	
	public List<Users> findRecorder(){
		try{	
			Criteria criteria = getSession().createCriteria(Users.class);
			criteria.add(Restrictions.eq("status", 1 ));
			criteria.add(Restrictions.eq("status2", "0" ));
			criteria.add(Restrictions.eq("decLevel", "4" ));
			criteria.add(Restrictions.eq("unitCode", "221" ));
			criteria.setCacheable(true);
			return getList(criteria);
		}catch( Exception e ){
			getLog().error(e.toString());
			return null;
		}
	}
	

}
